package edu.webtek.graven;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import org.jdom2.Document;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.XMLOutputter;

import edu.webtek.cloudreq.ReqAdjustItemStock;
import edu.webtek.cloudreq.ReqCreateCustommer;
import edu.webtek.cloudreq.ReqCreateItem;
import edu.webtek.cloudreq.ReqLogin;
import edu.webtek.cloudreq.ReqModifyItem;
import edu.webtek.cloudreq.ReqSellItems;
import edu.webtek.cloudresp.RespCreateCustomer;
import edu.webtek.cloudresp.RespCustomers;
import edu.webtek.cloudresp.RespItemID;
import edu.webtek.cloudresp.RespItems;
import edu.webtek.cloudresp.RespLogin;
import edu.webtek.cloudresp.RespSale;
import edu.webtek.cloudresp.RespSales;
import edu.webtek.cloudresp.RespShops;

public class CloudCommunication {
	private final String shopkey 		= "A00F5498EA6E0CBCF8FBF972";
	private final String cloudAddress 	= "http://services.brics.dk/java4/cloud";

	private final SAXBuilder xmlBuilder = new SAXBuilder();
	private final XMLOutputter xmlOut 	= new XMLOutputter();

	/**
	 * @return the shopkey
	 */
	public String getShopkey() {
		return shopkey;
	}

	/**
	 * @return the couldAddress
	 */
	public String getCloudAddress() {
		return cloudAddress;
	}

	private String createParamString(String key, String value)
			throws UnsupportedEncodingException {
		if(key == null || value == null){
			return "";
		}
		return "?"+key+"="+value;
	}

	private Document makeGetRequest(String address,
			String key, String value) {
		String url;
		HttpURLConnection con;
		try {
			url = getCloudAddress() + address + createParamString(key, value);
			con = (HttpURLConnection) new URL(url).openConnection();
			con.setRequestMethod("GET");
			return xmlBuilder.build(con.getInputStream());
		} catch (IOException | JDOMException e) {
			System.err.println(e.getMessage());
			return null;
		}
	}
	private Document makePostRequest(String address, Document payload) {
		String url;
		HttpURLConnection con;
		try {
			url = getCloudAddress() + address;
			con = (HttpURLConnection) new URL(url).openConnection();
			con.setRequestMethod("POST");
			con.setDoOutput (true);
			OutputStream reqStream;
			reqStream = con.getOutputStream();
			xmlOut.output(payload, reqStream);
			return xmlBuilder.build(con.getInputStream());
		} catch (IOException | JDOMException e) {
			System.err.println(e.getMessage());
			return null;
		}
	}
	/*
	 * cloud requests from here on down
	 */
	public RespLogin login(String custName, String custPass) {
		ReqLogin request = new ReqLogin(custName, custPass);
		Document reqDoc = request.toDocument();		
		return new RespLogin(makePostRequest("/login", reqDoc));
	}

	public RespSale sellItems(int itemID, int custommerID, int saleAmount) {
		ReqSellItems request = new ReqSellItems(getShopkey(), itemID,
				custommerID, saleAmount);
		Document reqDoc = request.toDocument();
		return new RespSale(makePostRequest("/sellItems", reqDoc));
	}

	public RespItemID createItem(String itemName) {
		ReqCreateItem request = new ReqCreateItem(getShopkey(), itemName);
		Document reqDoc = request.toDocument();
		return new RespItemID(makePostRequest("/createItem", reqDoc));
	}

	public RespCreateCustomer createCustomer(String custName, String custPass) {
		ReqCreateCustommer request = new ReqCreateCustommer(getShopkey(),
				custName, custPass);
		Document reqDoc = request.toDocument();
		return new RespCreateCustomer(
				makePostRequest("/createCustomer", reqDoc));
	}

	public void modifyItem(String itemName, String itemURL,
			String itemDescription, int itemID, int itemPrice) {
		ReqModifyItem request = new ReqModifyItem(getShopkey(), itemName,
				itemURL, itemDescription, itemID, itemPrice);
		Document reqDoc = request.toDocument();
		makePostRequest("/modifyItem", reqDoc);
	}

	public void adjustItemStock(int itemID, int adjustment) {
		ReqAdjustItemStock request = new ReqAdjustItemStock(getShopkey(),
				itemID, adjustment);
		Document reqDoc = request.toDocument();
		makePostRequest("/adjustItemStock", reqDoc);
	}
	
	public RespShops listShops(){
		Document out = makeGetRequest("/listShops", null, null);
		return new RespShops(out);
	}
	
	public RespItems listItems(int shopID){
		Document out = makeGetRequest("/listItems", "shopID", Integer.toString(shopID));
		return new RespItems(out);
	}
	
	public RespCustomers listCustomers(){
		Document out = makeGetRequest("/listCustomers", null, null);
		return new RespCustomers(out);
	}
	
	public RespSales listCustomerSales(int customerID){
		Document out = makeGetRequest("/listCustomerSales", "customerID", Integer.toString(customerID));
		return new RespSales(out);
	}
	
	public RespSales listShopSales(int shopID){		
		Document out = makeGetRequest("/listShopSales", "shopKey", Integer.toString(shopID));
		return new RespSales(out);
	}
}
